/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xenon3d.scene;

import java.util.EnumSet;

/**
 * SceneGraphObject is the common superclass for all scene graph objects.
 *
 * @author Volker Everts
 * @version 0.1 - 25.08.08: Created
 */
public abstract class SceneGraphObject {

    // <editor-fold defaultstate="collapsed" desc=" Private Fields ">

    /** The name of a SceneGraphObject (optional). */
    String name;

    /** The object id (optional). */
    int id;

    /** The user data object, can be used to store any kind of user data (optional). */
    Object userData;

    /** The node capabilities. */
    EnumSet<Capability> caps;

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Initialization ">

    /**
     * Creates a new scene graph object.
     */
    protected SceneGraphObject() {
        caps = EnumSet.noneOf(Capability.class);
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Public Properties ">

    /**
     * Sets the name of this object.
     * @param name the new name
     */
    public final void setName(String name) {
        this.name = name;
    }

    /**
     * Returns the name of this object.
     * @return the object's name
     */
    public final String getName() {
        return name;
    }

    /**
     * Sets the object id.
     * @param id the object id
     */
    public final void setId(int id) {
        this.id = id;
    }

    /**
     * Returns the object id.
     * @return the object id
     */
    public final int getId() {
        return id;
    }

    /**
     * Sets the user data object.
     * @param userData the user data object
     */
    public final void setUserData(Object userData) {
        this.userData = userData;
    }

    /**
     * Returns the user data object.
     * @return the user data object
     */
    public final Object getUserData() {
        return userData;
    }

    /**
     * Sets the specified capability.
     * @param cap the capability to set
     */
    public final void setCapability(Capability cap) {
        if (isLiveOrCompiled()) throw new RestrictedAccessException();
        caps.add(cap);
    }

    /**
     * Clears the specified capability.
     * @param cap the capability to clear
     */
    public final void clearCapability(Capability cap) {
        if (isLiveOrCompiled()) throw new RestrictedAccessException();
        caps.remove(cap);
    }

    /**
     * Returns whether the specified capability is set.
     * @param cap the capability to clear
     * @return true, if the capability is set
     */
    public final boolean isCapability(Capability cap) {
        return caps.contains(cap);
    }

    /**
     * Returns a flag indicating whether this object is part of a live scene
     * graph.
     * @return true, if this object is live
     */
    public abstract boolean isLive();

    /**
     * Returns a flag indicating whether this object is part of a compiled scene
     * graph.
     * @return true, if this object is compiled
     */
    public abstract boolean isCompiled();

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Package Private Methods ">

    /**
     * Returns a flag indicating whether or not this scene graph object is live
     * or compiled.
     * @return true, if this scene graph object is live or compiled
     */
    abstract boolean isLiveOrCompiled();

    /**
     * Checks whether this scene graph object is live or compiled, and if so,
     * throws an exception if the specified capability is not set.
     * @param cap the capability that must be set if live or compiled
     * @throws CapabilityNotSetException if the the object is live or compiled
     * and the specified capability is not set.
     */
    abstract void checkCapability(Capability cap);

    /**
     * Sets the live state of this scene graph object.
     */
    abstract void setLive();

    /**
     * Clears the live state of this scene graph object.
     */
    abstract void clearLive();

    /**
     * Sets the compiled state of this scene graph object.
     */
    abstract void setCompiled();

    /**
     * Clears the compiled state of this scene graph object.
     */
    abstract void clearCompiled();

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Implementation Object ">

    @Override
    public String toString() {
        if (name == null) return super.toString();
        return super.toString() + " <" + name + ":" + id + ">";
    }

    // </editor-fold>

} // end class SceneGraphObject